package cn.shop.gameapi.controller;

import cn.hutool.core.util.StrUtil;
import cn.shop.gameapi.model.*;
import cn.shop.gameapi.util.IdUtil;
import cn.shop.gameapi.util.IpUtil;
import cn.shop.gameapi.util.ResponseInfo;
import cn.shop.utils.Putif;
import cn.shop.utils.enums.OrderStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Map;

import static cn.shop.gameapi.model.SqlContent.*;

/**
 * @author : 李一涵
 * @date : Created in 2021-12-15 15:00
 * @description :
 */
@RestController
@RequestMapping("/{uid}/order")
public class OrderController {

    private static final Logger LOG = LoggerFactory.getLogger(OrderController.class);

    @Resource
    private JdbcTemplate jdbcTemplate;


    @Resource
    private IdUtil idUtil;

    @PostMapping("/add")
    public ResponseInfo<Map<String, Object>> addOrder(@PathVariable long uid, @RequestBody GameOrder o, HttpServletRequest request) {
        String ip = IpUtil.getClientIp(request);
        String secret = request.getHeader("secret");
        GatewaySecret gs = null;
        try {
            gs = jdbcTemplate.queryForObject(SELECT_SECRET_IP, new BeanPropertyRowMapper<>(GatewaySecret.class), ip);
        } catch (EmptyResultDataAccessException ignored) {}
        Map<String, Object> failMap = Putif.start()
                .anyway("success", 0)
                .anyway("fail", 1)
                .get();
        if (gs == null || StrUtil.isBlank(secret) || !StrUtil.equals(gs.getSecret(), secret)) {
            return ResponseInfo.failed(failMap);
        }
        if (o == null) {
            return ResponseInfo.failed(failMap);
        }
        LOG.info("收到网关的订单数据：{}", o);
        MerchantGameTemplate template = null;
        try {
            template = jdbcTemplate.queryForObject(SELECT_TEMPLATE_ID,
                    new BeanPropertyRowMapper<>(MerchantGameTemplate.class), o.getTemplateId());
        } catch (Exception ignored) {}
        if (template == null) {
            LOG.warn("模板信息不存在 {}", o);
            failMap.put("message", "模板信息不存在");
            return ResponseInfo.failed(failMap);
        }
        MerchantGamePartition partition = null;
        try {
            partition = jdbcTemplate.queryForObject(SELECT_PARTITION,
                    new BeanPropertyRowMapper<>(MerchantGamePartition.class), o.getPartitionId());
        } catch (Exception ignored) {}
        if (partition == null) {
            LOG.warn("分区信息不存在 {}", o);
            failMap.put("message", "分区信息不存在");
            return ResponseInfo.failed(failMap);
        }
        if (!partition.getTemplateId().equals(template.getId())) {
            LOG.warn("模板信息不一致 {}", o);
            failMap.put("message", "模板信息不一致");
            return ResponseInfo.failed(failMap);
        }
        double charge = template.getCharge();
        try {
            GameBind gameBind = null;
            try {
                gameBind = jdbcTemplate.queryForObject(SELECT_BIND, new BeanPropertyRowMapper<>(GameBind.class)
                        , o.getPlayAccount(), o.getPartitionId(), o.getPlayNickname());
                LOG.info("查到的卖家信息: {}", gameBind);
            } catch (Exception e) {
                LOG.warn("查询卖家信息失败：", e);
            }
            if (gameBind == null) {
                LOG.info("订单 {}， 未查到卖家信息", o);
                failMap.put("message", "未查到卖家信息");
                return ResponseInfo.failed(failMap);
            }
            Object[] param = format(o, uid, charge, gameBind);
            int count = jdbcTemplate.update(INSERT_ORDER, param);
            if (count > 0) {
                return ResponseInfo.ok(Putif.start()
                        .anyway("success", 1)
                        .get());
            } else {
                return ResponseInfo.failed(failMap);
            }
        } catch (Exception e) {
            LOG.warn("保存订单出错:{}", o, e);
            return ResponseInfo.failed(failMap);
        }
    }

    private Object[] format(GameOrder order, long uid, double charge, GameBind gameBind) {
        LOG.info("格式化订单: {}", order);
        LocalDateTime now = LocalDateTime.now();
        return new Object[] {
                idUtil.getId(uid),
                uid,
                order.getTemplateId(),
                order.getPartitionId(),
                gameBind.getUserId(),
                order.getPlayAccount(),
                order.getPlayNickname(),
                order.getItem(),
                order.getNum(),
                order.getBack(),
                order.getAmount(),
                OrderStatus.AUDITING.code(),
                charge,
                now,
                false,
                now,
                1
        };
    }

}
